#!/usr/bin/env python

#################################################################################
#
# Copyright (c) 2006 Michigan State University
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#################################################################################

#################################################################################
#
#	Author:
#		Nathan Collins <npcollins@gmail.com>
#
#################################################################################

# imports
from dbinter import *
from terms import shorten
from util import *

def printDirectory(parentHash = 'ROOT',suggestdir = 0, viewparent = 0):
	"""
	Prints the root directory in navigatable HMTL form.
	
	Called from the index page. suggestdir makes the directory use ajax functions
	for suggestions. viewparent means the recHash was passed, and the parentHash
	must be looked up.
	"""

	if viewparent == '1':
		rec = quick_query("SELECT * FROM directoryTree WHERE recHash = '%s';" % parentHash)
		if len(rec) < 1:
			print 'Invalid record.'
			raise

		# parentHash of record
		parentHash = rec[0]['parentHash']

	dirQuery = "SELECT * FROM directoryTree WHERE parentHash = '%s';" % parentHash
	listing = quick_query(dirQuery)

	dirOut = directoryOutput(listing,suggestdir)
	dirOut.process(parentHash)


class directoryOutput:
	"""
	Organize and print out the directory listing.
	"""
	def __init__(self, listing, suggest):
		# listing of results
		self.listing = listing
		# is this a suggestion browse?
		self.suggest = suggest
		# sub-directories
		self.subs = []
		# links
		self.links = []
		# records
		self.recs = []
		# parentHash
		self.parentHash = 'ROOT'

	def process(self,parentHash = 'ROOT'):
		self.parentHash = parentHash
		self.sortListing()
		print '<div id="directoryDiv" align="center">'
		self.printSubs()
		if self.suggest == 0: self.printLink()
		print '<hr>'
		if self.suggest == 0:
			self.printRecs()
			self.printSugg()
		print '</div>'

	def printSugg(self):
		# print options to suggest a directory/link
		print """
		<div id="suggestdiv">
		<a href="suggest.py?d=%s" onclick="rememberLocation();">Suggest Directory/Link</a>
		</div>""" % self.parentHash

	def printCrumbs(self, parentHash = '', quiet = 0):
		if parentHash == '': parentHash = self.parentHash
		# print the breadcrumbs for upward navigation
		db = oai_db()
		db.connect()
		
		bc = []
		# retrieve breadcrumb list
		while parentHash != 'ROOT':
			bcQuery = "SELECT parentHash,recHash,entryTitle FROM directoryTree WHERE recHash = '%s' AND isLink = 'N';" % parentHash
			# this is here to catch if we somehow got into someplace which is not
			# in ROOT's tree - prevent infinite loop and such
			parentHash = 'ROOT'
			
			(fields,rows) = db.query(bcQuery)
			if rows != None:
				# get field names
				dKeys = [field[0] for field in fields]

				for row in rows:
					recLevel = dict(zip(dKeys,row))
				bc.append(recLevel)
				parentHash = recLevel['parentHash']

		bc.reverse()
		self.outCrumbs(bc)

		db.disconnect()
		print '<br>'
		# print the obvious
		if quiet == 0 and len(self.listing) < 1: 
			print """<span class="smallish"><br>
			<b>This directory does not contain any records.</b>
			<i>You can help the expand the directory by submitting suggestions
			of articles to the directory.</i><br><br>
			Perform searches using OAIS and click 'Expand' next to an article
			you think would be appropriate in the directory. Edit the title and
			description to make it concise and directory friendly. Then use the
			directory navigation under the suggestion form to navigate to a
			place in the directory that you feel the article belongs.<br><br>
			Once submitted, it will be reviewed by an editor before being placed
			into the directory.<br><br>
			You can also suggest new directories or a links to another part of
			the directory by using 'Suggest Directory/Link' below.</span>
			"""

	def outCrumbs(self, crumbList):
		# top level
		if self.suggest == 0:
			print '<i>Location</i> &raquo; <a href="index.py?d=1">Top</a>'
		else:
			print '<i>Location</i> &raquo; <a class="fakelink" onClick="updateParent(\'ROOT\'); sendSuggestDir(\'ROOT\');">Top</a>'
		for c in crumbList:
			if self.suggest == 0:
				print ' &raquo; <a href="index.py?d=%s">%s</a>' % (c['recHash'], c['entryTitle'])
			else:
				print ' &raquo; <a class="fakelink" onClick="updateParent(\'%s\'); sendSuggestDir(\'%s\');">%s</a>' % (c['recHash'], c['recHash'], c['entryTitle'])

	def sortListing(self):
		for part in self.listing:
			if part['isDirectory'] == 'Y':
				self.subs.append(part)	
			elif part['isLink'] == 'Y':
				self.links.append(part)	
			elif part['isRecord'] == 'Y':
				self.recs.append(part)

		self.subs = sortListDict(self.subs, 'entryTitle')
		self.links = sortListDict(self.links, 'entryTitle')
		self.recs = sortListDict(self.recs, 'entryTitle')

	def printSubs(self):
		# table header
		print '<div class="barLight"><b>Directory</b></div>'
		print '<table class="directoryTable"><tr><td colspan="2">'
		self.printCrumbs()
		if len(self.subs) > 0:
			print '</td></tr><tr><td width="50%" class="directoryCell">'
			
			half = 1
			if len(self.subs) > 1: half = int( len(self.subs) / 2 )
			# check for remainder
			mid = 0
			if len(self.subs) % 2 != 0: mid = 1
			
			for sub in self.subs[:half+mid]:
				self.outDirectory(sub)

			print '</td><td width="50%" class="directoryCell">'
			
			if len(self.subs) > 1:
				# only if there is more than 1 directory
				for sub in self.subs[-half:]:
					self.outDirectory(sub)

		# table footer
		print '</td></tr></table>'

	def printLink(self):
		# table header
		print '<table class="directoryTable"><tr><td colspan="2">'
		if len(self.links) > 0:
			print '<i>Links</i>'
			print '</td></tr><tr><td width="50%" class="directoryCell">'
			
			half = 1
			if len(self.links) > 1: half = int( len(self.links) / 2 )
			# check for remainder
			mid = 0
			if len(self.links) % 2 != 0: mid = 1
			
			for sub in self.links[:half+mid]:
				self.outLink(sub)

			print '</td><td width="50%" class="directoryCell">'
			
			if len(self.links) > 1:
				# only if there is more than 1 directory
				for sub in self.links[-half:]:
					self.outLink(sub)

		# table footer
		print '</td></tr></table>'

	def printRecs(self):
		# print records
		for rec in self.recs:
			self.outRecord(rec)
		
	
	def outDirectory(self, rec):
		linkTitle = shorten(rec['entryTitle'], 80)
		linkDesc = shorten(rec['entryDescription'], 100)
		# for browsing the directory
		if self.suggest == 0:
			print '<a href="index.py?d=%s">%s</a>' % (rec['recHash'],linkTitle)
			print '&nbsp;&nbsp;<a class="noul" href="suggest.py?m=%s" onclick="rememberLocation();"><span class="details">Modify</span></a>' % rec['recHash']
			print '<br><span class="smallish">%s</span><br>' % linkDesc
		# for making a suggestion to the directory
		elif self.suggest == 1:
			print '<a class="fakelink" onClick="updateParent(\'%s\'); sendSuggestDir(\'%s\');">%s</a><br>' % (rec['recHash'], rec['recHash'], linkTitle)
			print '<span class="smallish">%s</span><br><br>' % linkDesc

	def outLink(self, rec):
		linkTitle = shorten(rec['entryTitle'], 80)
		linkDesc = shorten(rec['entryDescription'], 120)
		print '<a href="index.py?d=%s">%s</a>' % (rec['targetHash'],linkTitle)
		print '&nbsp;&nbsp;<a class="noul" href="suggest.py?m=%s" onclick="rememberLocation();"><span class="details">Modify</span></a>' % rec['recHash']
		print '<br><span class="smallish">%s</span><br>' % linkDesc

	def outRecord(self, rec):
		title = shorten(rec['entryTitle'],120)
		desc = shorten(rec['entryDescription'], 300)
		print '<p align="left"><a href="%s">%s</a>' % (rec['entryLink'],title)
		# only print metadata link if internal
		if rec['isExternal'] == 'N':
			print '&nbsp;&nbsp;<a class="noul" href="search.py?s=rec%%3a%s&e=1"><span class="details">Metadata</span></a>' % rec['recHash']
		else:
			# print external symbol
			print '&nbsp;&nbsp;<a title="No Metadata. Added from external source.">&#8999;</a>'
		print '&nbsp;&nbsp;<a class="noul" href="suggest.py?m=%s" onclick="rememberLocation();"><span class="details">Modify</span></a>' % rec['recHash']
		print '<br><span class="smallish">'+ desc + '</span></p>'

# given a record dict, return the type of record
def getDirType(recdict):
	types = ['isDirectory','isLink','isRecord']
	for type in types:
		if recdict[type] == 'Y':
			# pass over the first two chars, dropping the 'is'
			return type[2:]
	# this happens when a record is bad
	return ''

def directoryHash(parentHash,title):
	# generate a hash for a directory or link
	db = oai_db()
	db.connect()

	bc = []
	while parentHash != 'ROOT':
		q = "SELECT parentHash, recHash, entryTitle FROM directoryTree WHERE recHash = %s;"
		(fields,rows) = db.query_args( q, (parentHash,) )

		# catch for loops
		parentHash = 'ROOT'

		if rows != None:
			dKeys = [field[0] for field in fields]

			for row in rows:
				recLevel = dict(zip(dKeys,row))

			bc.append(recLevel['entryTitle'])
			parentHash = recLevel['parentHash']

	db.disconnect()

	dirHash = 'ROOT'
	for c in bc:
		dirHash += '.' + c

	dirHash += '.' + title

	return make_hash(dirHash)

# eof

